package org.xs.object;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.time.Duration;
import java.util.concurrent.Executors;

@RestController
public class SseController {

    @GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> sseStream() {
        return Flux.interval(Duration.ofSeconds(1))
                .map(sequence -> "Event: " + sequence);
    }
    @GetMapping("/events/complex")
    public SseEmitter streamEvents() {
        // 创建 SseEmitter 对象
        SseEmitter emitter = new SseEmitter();

        Executors.newSingleThreadExecutor().submit(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    // 发送事件
                    emitter.send(SseEmitter.event()
                            .name("custom-event")
                            .data("Message " + i));

                    Thread.sleep(1000);
                }
                emitter.complete();
            } catch (Exception ex) {
                emitter.completeWithError(ex);
            }
        });

        return emitter;
    }

    @GetMapping("/bulk-events")
    public SseEmitter bulkEvents() {
        SseEmitter emitter = new SseEmitter();

        Executors.newSingleThreadExecutor().execute(() -> {
            try {
                for (int i = 0; i < 1000; i += 100) {
                    StringBuilder batch = new StringBuilder();
                    for (int j = i; j < i + 100 && j < 1000; j++) {
                        batch.append("Data").append(j).append("\n");
                    }
                    emitter.send(batch.toString());
                    Thread.sleep(500);
                }
                emitter.complete();
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        });

        return emitter;
    }

    @GetMapping("/events-with-id")
    public Flux<Event> eventsWithId() {
        return Flux.interval(Duration.ofSeconds(2))
                .map(seq ->
                        Event.builder()
                                .id(String.valueOf(seq))
                                .name("status-update")
                                .data("System status: OK")
                                .build()
                );
    }

    // 事件类定义
    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Event {
        private String id;
        private String name;
        private Object data;
    }

}
